package com.gxa.ssm251.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

/**
 * DBUtil操作数据库的基本工具类
 * @author bilei
 */

public class DBUtil {

    private Connection connection = null;
    private PreparedStatement preparedStatement = null;
    private ResultSet resultSet = null;

    private String url;
    private String driver;
    private String user;
    private String password;


    // 使用类声明的语句块
    // 保证能在获得连接之前先执行
    {
        //结合IO和静态语句块的功能,加载配置文件
        // 让自定义配置项加载工具Properties实例化,并且和配置文件绑定
        // 实例化一个Properties的对象
        Properties properties = new Properties();

        try {
            // 服务器不能使用FileInputStream
            //在服务器中依然使用ClassLoader加载

            ClassLoader classLoader = DBUtil.class.getClassLoader();
            InputStream resourceAsStream = classLoader.getResourceAsStream("properties/db.properties");


            // 属性集对象通过文件字节流加载文件配置
            properties.load(resourceAsStream);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");

            //加载驱动
            Class.forName(driver);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    /**
     * 建立连接的方法
     *  @return Connection 连接对象
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    private Connection getConnection() throws Exception{
        connection = DriverManager.getConnection(url, user, password);
        return connection;
    }

    /**
     * 获取预编译语句对象的方法
     * @param sql 预编译的SQL命令
     * @return PreparedStatement对象
     * @throws Exception
     */
    public PreparedStatement getPreparedStatement(String sql) throws Exception{
        preparedStatement= getConnection().prepareStatement(sql);
        return preparedStatement;
    }

    /**
     * 执行增删改的方法, 执行完毕,回收所有资源
     * @param preparedStatement 执行增删改语句的且预编译完成,且如果有参数就带参的命令对象
     * @return 返回影响的行数
     * @throws SQLException
     */
    public int execUpdate(PreparedStatement preparedStatement) throws SQLException{
        return  preparedStatement.executeUpdate();
    }

    /**
     * 执行查询的方法, 执行完毕,回收所有资源
     * @param preparedStatement 执行查询语句的对象
     * @return 返回相应的结果集
     * @throws SQLException
     */
    public ResultSet  execQuery(PreparedStatement preparedStatement) throws SQLException{
        resultSet = preparedStatement.executeQuery();
        return resultSet;
    }


    /**
     *关闭结果集对象
     */
    public void closeSet() throws SQLException{
        if(resultSet!=null){
            resultSet.close();
        }
    }

    /**
     *关闭预编译对象
     */
    public void closePrepStat() throws SQLException{
        if(preparedStatement!=null){
            preparedStatement.close();
        }
    }

    /**
     *关闭连接对象
     */
    public void closeConn() throws SQLException{
        if(connection!=null) {
            connection.close();
        }
    }

    /**
     *关闭全部对象,调用其它三个关闭方法
     */
    public void closeAll() throws SQLException{
        closeSet();
        closePrepStat();
        closeConn();
    }


}
